package com.proxy.server.context;

import com.proxy.common.model.DataNode;
import com.proxy.common.model.FrontendProxy;
import com.proxy.common.utils.ExecutorUtil;
import com.proxy.server.backend.BackendClient;
import com.proxy.server.backend.bio.BioBackendClient;
import com.proxy.server.backend.nio.NioBackendClient;
import com.proxy.server.frontend.session.Session;
import io.netty.channel.Channel;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 上下文,采用单例模式
 *
 * Created by liufish on 16/7/14.
 */
public class AppContext {

    /**
     * 前端代理信息
     */
    private FrontendProxy frontendProxy;

    /**
     * 逻辑任务线程池
     */
    private ThreadPoolExecutor proxyExecutor;

    /**
     * 后端代理节点
     */
    private List<BackendClient> clients = new ArrayList<>();

    /**
     * 单例关键字private
     */
    private AppContext() {
    }

    /**
     * 单例关键类
     */
    private static class AppContextHolder {
        private static final AppContext INSTANCE = new AppContext();
    }

    /**
     * 单例关键变量
     */
    public static final AppContext getInstance() {
        return AppContextHolder.INSTANCE;
    }

    /**
     * 注册session
     * @param channel
     * @param session
     */
    public void registeredSession(Channel channel,Session session){
        AppDataStore.sessionMap.put(channel,session);
    }

    /**
     * 移除注册session
     * @param channel
     */
    public void unRegisteredDession(Channel channel){
        AppDataStore.sessionMap.remove(channel);
        channel.close();
    }

    /**
     * 获取注册session
     * @param channel
     */
    public Session getProxySession(Channel channel){
        return AppDataStore.sessionMap.get(channel);
    }


    /**
     * 初始化信息
     */
    public void init(){

        //防止多次启动
        if(frontendProxy != null){
            return;
        }

        String jsonPath = getClass().getResource("/proxy.json").getPath();
        ProxyInitialize initialize = new ProxyInitialize(jsonPath);
        frontendProxy = initialize.getFrontendProxy();
        for(DataNode node : initialize.getNodes()){
            BackendClient client = null;
            if(frontendProxy.isBio()){
                client = new BioBackendClient(node);
            }else {
                client = new NioBackendClient(node);
            }
            clients.add(client);
        }
    }

    /**
     * 获取前端信息
     */
    public FrontendProxy getFrontendProxy(){
        return this.frontendProxy;
    }


    /**
     * 获取线程池
     */
    public ThreadPoolExecutor getProxyExecutor() {
        if(proxyExecutor == null){
            proxyExecutor = ExecutorUtil.create("proxy_",frontendProxy.getExecutor());
        }
        return proxyExecutor;
    }

    /**
     * 获取后端连接
     */
    public List<BackendClient> getClients(){
        return this.clients;
    }


}
